<template>
    <ACard :title="showTitle">
        <div class="container_warp">
            <div id="containerChart"></div>
            <RightDrawer
                class="right_drawer"
                :drawer-type="type"
                :select-cell.sync="selectCell"
                :graph="graph"
                :grid="grid"
                @deleteNode="deleteNode"
            />
            <div class="operating">
                <div class="btn-group">
                    <div
                        class="btn"
                        title="圆形节点"
                        @mousedown="startDrag('Circle', $event)"
                    >
                        <i class="iconfont icon-circle"></i>
                    </div>
                    <div
                        class="btn"
                        title="正方形节点"
                        @mousedown="startDrag('Rect', $event)"
                    >
                        <i class="iconfont icon-square"></i>
                    </div>
                    <div class="btn" title="条件节点">
                        <i
                            class="iconfont icon-square rotate-square"
                            @mousedown="startDrag('polygon', $event)"
                        ></i>
                    </div>
                    <div v-if="showTips" class="btn-group_tips">
                        拖拽生成<br />资产拓扑图形
                    </div>
                </div>
                <div class="btn-group">
                    <ATooltip title="直线箭头" placement="bottom">
                        <div
                            :class="[
                                'btn',
                                currentArrow === 1 ? 'currentArrow' : '',
                            ]"
                            @click="changeEdgeType('normal')"
                        >
                            <i class="iconfont icon-ai28"></i>
                        </div>
                    </ATooltip>
                    <ATooltip title="曲线箭头" placement="bottom">
                        <div
                            :class="[
                                'btn',
                                currentArrow === 2 ? 'currentArrow' : '',
                            ]"
                            @click="changeEdgeType('smooth')"
                        >
                            <i class="iconfont icon-Down-Right"></i>
                        </div>
                    </ATooltip>
                    <ATooltip title="直角箭头" placement="bottom">
                        <div
                            :class="[
                                'btn',
                                currentArrow === 3 ? 'currentArrow' : '',
                            ]"
                            @click="changeEdgeType()"
                        >
                            <i class="iconfont icon-jiantou"></i>
                        </div>
                    </ATooltip>
                </div>
                <div class="btn-group">
                    <ATooltip title="删除" placement="bottom">
                        <div
                            class="btn"
                            style="margin-top: 5px"
                            @click="deleteNode()"
                        >
                            <i class="iconfont icon-shanchu"></i>
                        </div>
                    </ATooltip>
                    <ATooltip cotitlentent="保存PNG" placement="bottom">
                        <div class="btn" title="保存" @click="saveToPNG()">
                            <i class="iconfont icon-baocun"></i>
                        </div>
                    </ATooltip>
                </div>
                <div class="btn-group">
                    <ATooltip title="返回" placement="bottom" @click="onUndo()">
                        <div class="btn">
                            <!-- <i class="iconfont icon-shangyibu"></i> -->
                            <svg
                                t="1691635330167"
                                class="icon"
                                viewBox="0 0 1024 1024"
                                version="1.1"
                                xmlns="http://www.w3.org/2000/svg"
                                p-id="5822"
                                width="20"
                                height="20"
                            >
                                <path
                                    d="M995.648 459.296C684.448 281.568 406.08 318.656 171.232 567.904L32 416v384h352l-160.736-175.328c211.168-227.072 452.192-259.776 734.304-98.688a38.4 38.4 0 0 0 38.08-66.688z"
                                    p-id="5823"
                                />
                            </svg>
                        </div>
                    </ATooltip>
                    <ATooltip title="还原" placement="bottom" @click="onRedo()">
                        <div class="btn">
                            <svg
                                t="1691635422370"
                                class="icon"
                                viewBox="0 0 1024 1024"
                                version="1.1"
                                xmlns="http://www.w3.org/2000/svg"
                                p-id="6984"
                                width="20"
                                height="20"
                            >
                                <path
                                    d="M860.992 558.912C627.904 317.536 352.384 283.648 44.8 459.296a38.4 38.4 0 1 0 38.08 66.688c278.432-159.008 516.896-129.408 726.08 89.696L640 800h352V416l-131.008 142.912z"
                                    p-id="6985"
                                />
                            </svg>
                        </div>
                    </ATooltip>
                </div>
            </div>
        </div>
    </ACard>
</template>

<script>
/* eslint-disable */
import "@antv/x6-vue-shape";
import { Graph, Shape, FunctionExt } from "@antv/x6";
import RightDrawer from "./components/RightDrawer";
import insertCss from "insert-css";
import { startDragToGraph } from "./Graph/methods.js";
const data = {};
const s = "fromJSON";
export default {
    name: "X6Element",
    components: {
        RightDrawer,
    },
    props: {
        isToPng: {
            type: Boolean,
            default: false,
        },
        isToJsonData: {
            type: Boolean,
            default: false,
        },
        isLookOver: {
            type: Boolean,
            default: false,
        },
        http: Function,
        // detail
        value: Object,
    },
    data() {
        return {
            graph: "",
            value1: true,
            type: "grid",
            selectCell: "",
            connectEdgeType: {
                //连线方式
                connector: "normal",
                router: {
                    name: "",
                },
            },
            showTips: false,
            currentArrow: 1,
            grid: {
                // 网格设置
                size: 20, // 网格大小 10px
                visible: true, // 渲染网格背景
                type: "mesh",
                args: {
                    color: "#D0D0D0",
                    thickness: 2, // 网格线宽度/网格点大小
                    factor: 10,
                },
            },
            history: undefined,
            canUndo: true,
            canRedo: false,
            id: undefined,
        };
    },
    computed: {
        showTitle() {
            if (this.id && !this.isLookOver) {
                return "编辑流程图";
            } else if (!this.id && !this.isLookOver) {
                return "新增流程图";
            } else if (this.id && this.isLookOver) {
                return "查看流程图";
            }
        },
    },
    mounted() {
        this.initX6();
        this.showTip();
    },
    beforeDestroy() {
        if (this.graph) {
            this.graph.dispose();
        }
    },
    methods: {
        getData() {
            const { id } = this.$route.query;
            if (id) {
                this.id = id;
                if (!this.http) {
                    // 调接口 --- > 拿数据
                    this.http(this.id)
                        .then((res) => {
                            console.log(res, "res流程图");
                            // 回显 x6 节点
                            // this.graph[s](res.data);
                        })
                        .catch((err) => err);
                } else {
                    this.graph[s](data);
                }
            } else if (this.value) {
                this.graph[s](this.value);
            }
        },
        initX6() {
            let _that = this;
            _that.graph = new Graph({
                container: document.getElementById("containerChart"),
                history: true,
                width: 1000,
                height: "100%",
                grid: _that.grid,
                resizing: {
                    //调整节点宽高
                    enabled: true,
                    orthogonal: false,
                },
                // 对齐线是移动节点排版的辅助工具
                snapline: {
                    enabled: true,
                },
                // panning: {
                //     enabled: true,
                //     modifiers: "shift",
                // },
                // 画布 可 滚动
                // scroller: {
                //     enabled: true,
                //     pannable: true,
                //     pageVisible: true,
                //     pageBreak: false,
                // },
                // mousewheel: {
                //     enabled: true,
                //     modifiers: ['ctrl', 'meta'],
                // },
                selecting: true, //可选
                snapline: true,
                interacting: {
                    edgeLabelMovable: true,
                },
                connecting: {
                    // 节点连接
                    anchor: "center",
                    connectionPoint: "anchor",
                    allowBlank: false,
                    snap: true,
                    createEdge() {
                        return new Shape.Edge({
                            attrs: {
                                line: {
                                    stroke: "#1890ff",
                                    strokeWidth: 1,
                                    targetMarker: {
                                        name: "classic",
                                        size: 8,
                                    },
                                    strokeDasharray: 0, //虚线
                                    style: {
                                        animation:
                                            "ant-line 30s infinite linear",
                                    },
                                },
                            },
                            label: {
                                text: "",
                            },
                            connector: _that.connectEdgeType.connector,
                            router: {
                                name: _that.connectEdgeType.router.name || "",
                            },
                            zIndex: 0,
                        });
                    },
                },
                highlighting: {
                    magnetAvailable: {
                        name: "stroke",
                        args: {
                            padding: 4,
                            attrs: {
                                strokeWidth: 4,
                                stroke: "#6a6c8a",
                            },
                        },
                    },
                },
            });

            // if (_that.graph.isSnaplineEnabled()) {
            //     _that.graph.disableSnapline();
            // } else {
            //     _that.graph.enableSnapline();
            // }

            insertCss(`
              @keyframes ant-line {
                to {
                    stroke-dashoffset: -1000
                }
              }
            `);

            // update
            _that.getData();
            // this.graph.fromJSON(data);

            // 节点 操作： 返回上一步...
            _that.history = this.graph.history;

            // 鼠标移入移出节点
            _that.graph.on(
                "node:mouseenter",
                FunctionExt.debounce(() => {
                    const container = document.getElementById("containerChart");
                    const ports = container.querySelectorAll(".x6-port-body");
                    this.showPorts(ports, true);
                }),
                500
            );

            _that.graph.on("node:mouseleave", () => {
                const container = document.getElementById("containerChart");
                const ports = container.querySelectorAll(".x6-port-body");
                _that.showPorts(ports, false);
            });
            // 点击 画布
            _that.graph.on("blank:click", () => {
                _that.type = "grid";
                // this.nodeId = undefined
            });

            // 点击 节点 --- >
            _that.graph.on("cell:click", ({ cell }) => {
                if (this.isLookOver)
                    return _that.$message.info("只可查看,不可操作!");
                _that.type = cell.isNode() ? "node" : "edge";
            });
            _that.graph.on("selection:changed", (args) => {
                args.added.forEach((cell) => {
                    _that.selectCell = cell;
                    if (cell.isEdge()) {
                        cell.isEdge() && cell.attr("line/strokeDasharray", 5); //虚线蚂蚁线
                        cell.addTools([
                            {
                                name: "vertices",
                                args: {
                                    padding: 4,
                                    attrs: {
                                        strokeWidth: 0.1,
                                        stroke: "#2d8cf0",
                                        fill: "#ffffff",
                                    },
                                },
                            },
                        ]);
                    }
                });
                args.removed.forEach((cell) => {
                    cell.isEdge() && cell.attr("line/strokeDasharray", 0); //正常线
                    cell.removeTools();
                });
            });
        },
        showPorts(ports, show) {
            for (let i = 0, len = ports.length; i < len; i = i + 1) {
                ports[i].style.visibility = show ? "visible" : "hidden";
            }
        },
        // 撤销操作
        onUndo() {
            // if (this.isLookOver) return this.$message.info('只可查看,不可操作!')
            this.history.undo();
        },
        onRedo() {
            // if (this.isLookOver) return this.$message.info('只可查看,不可操作!')
            this.history.redo();
        },
        // 拖拽生成正方形或者圆形
        startDrag(type, e) {
            if (this.isLookOver)
                return this.$message.info("只可查看,不可操作!");
            // this.nodeId = undefined
            startDragToGraph(this.graph, type, e);
        },
        // 删除节点
        deleteNode() {
            if (this.isLookOver)
                return this.$message.info("只可查看,不可操作!");

            const cell = this.graph.getSelectedCells();
            this.graph.removeCells(cell);
            this.type = "grid";
        },
        // 保存png / json 数据
        saveToPNG() {
            if (this.isLookOver)
                return this.$message.info("只可查看,不可操作!");
            this.$nextTick(() => {
                // 1. 转为图片
                if (this.isToPng) {
                    this.graph.toPNG((dataUri) => {
                        // 下载 根据实际情况 是否打开
                        // DataUri.downloadDataUri(dataUri, '资产拓扑图.png');
                        // 将 base 64 抛出去
                        this.$emit("setBase64Data", dataUri, this.id);
                    });
                } else if (this.isToJsonData) {
                    // 2. 转换为 json 作为参数 传递给后端
                    const data = JSON.stringify(
                        this.graph.toJSON({ deep: true })
                    );
                    if (JSON.parse(data).cells.length === 0)
                        return this.$message.error("节点流程不能为空");
                    // 把json 数据 抛出去
                    this.$emit("setX6JsonData", data, this.id);
                } else if (this.isToJsonData && this.isToPng) {
                    // 3. 两种情况都存在
                    this.graph.toPNG((dataUri) => {
                        // 下载: 根据实际情况 是否打开
                        // DataUri.downloadDataUri(dataUri, '资产拓扑图.png');
                        // 将 base 64 抛出去
                        this.$emit("setBase64Data", dataUri, this.id);
                    });
                    // 把 json 数据抛出去
                    const data = JSON.stringify(
                        this.graph.toJSON({ deep: true })
                    );
                    this.$emit("setX6JsonData", data, this.id);
                }
            });
        },
        // 改变边形状
        changeEdgeType(e) {
            if (e === "normal") {
                this.connectEdgeType = {
                    connector: "normal",
                    router: { name: "" },
                };
                this.currentArrow = 1;
            } else if (e === "smooth") {
                this.connectEdgeType = {
                    connector: "smooth",
                    router: { name: "" },
                };
                this.currentArrow = 2;
            } else {
                this.connectEdgeType = {
                    connector: "normal",
                    router: { name: "manhattan" },
                };
                this.currentArrow = 3;
            }
        },
        showTip() {
            setTimeout(() => {
                this.showTips = true;
            }, 1000);
            setTimeout(() => {
                this.showTips = false;
            }, 5000);
        },
    },
};
</script>
<style lang="less">
@import "./font/iconfont.css";
@import "./index.less";
</style>
